package cts.com.servlet;

import java.io.IOException;
import java.sql.SQLException;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cts.com.dbmanager.DepositWithdrawlCash;
import cts.com.dbmanager.util.DMLOperationDbManager;
import cts.com.exception.TransactionException;
import cts.com.jaxb.TransactionBean;

/**
 * Servlet implementation class AvailableBalanceServlet
 */
public class TransactionServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	DepositWithdrawlCash depositWithdrawlCash;
	DMLOperationDbManager dmlOperaionDbManager;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public TransactionServlet() {
		super();
		depositWithdrawlCash = new DepositWithdrawlCash();
		dmlOperaionDbManager = new DMLOperationDbManager();
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		String accountNumber = (String) request.getParameter("txtAcNo");
		String operationToPerform = (String) request.getParameter("operation");
		response.setContentType("text/html");
		if (null != request.getParameter("sameBank")) {
			boolean isSameBankBeneficiary = Boolean
					.parseBoolean((String) request.getParameter("sameBank"));
			String pAcNo = (String) request.getParameter("txtPrimaryAcNo");
			String bAcNo = (String) request.getParameter("txtBeneficiaryAcNo");
			String bAcName = (String) request
					.getParameter("txtBeneficiaryName");
			String bIFSC = (String) request.getParameter("txtBeneficiaryIFSC");
			String bEmail = (String) request
					.getParameter("txtBeneficiaryEmail");
			String bPhNo = (String) request.getParameter("txtBeneficiaryPhNo");
			String bBankName=(String) request.getParameter("txtBeneficiaryBank");

			if (isSameBankBeneficiary) {
				if ("addBeneficiary".equalsIgnoreCase(operationToPerform)) {
					addBeneficiaryAccount(response, pAcNo, bAcNo, bAcName,
							bIFSC, bEmail, bPhNo, bBankName==null?"CBS":bBankName);
				}else if("deleteBeneficiary".equalsIgnoreCase(operationToPerform)) {
					deleteBeneficiaryAccount(response, pAcNo, bAcNo);
				}
			}else{
				if ("addBeneficiary".equalsIgnoreCase(operationToPerform)) {
					addBeneficiaryAccount(response, pAcNo, bAcNo, bAcName,
							bIFSC, bEmail, bPhNo, bBankName);
				}else if("deleteBeneficiary".equalsIgnoreCase(operationToPerform)) {
					deleteBeneficiaryAccount(response, pAcNo, bAcNo);
				}
			}
		}
		String accountBalance = "";

		if ("availableBalance".equalsIgnoreCase(operationToPerform)) {
			showAvailableBalance(response, accountNumber, accountBalance);
		} else if ("deposit".equalsIgnoreCase(operationToPerform)
				|| "withdraw".equalsIgnoreCase(operationToPerform)) {
			double transactionAmount = Double.parseDouble(String
					.valueOf(request.getParameter("txtAmt")));
			
			TransactionBean transactionBean = new TransactionBean();
			//From A/c Set
			transactionBean.setFromAccountNo(accountNumber);
			//From IFSC Set
			setFromIFSCInTransactionBean(accountNumber, transactionBean);
			//Transaction TimeStamp Set
			setTransactionTime(transactionBean);
			//Transaction Amount Set
			setTransactionAmount(transactionAmount,transactionBean);
			if ("deposit".equalsIgnoreCase(operationToPerform)) {
				doDepositLogic(response, accountNumber, accountBalance,
						transactionAmount, transactionBean);
			} else if ("withdraw".equalsIgnoreCase(operationToPerform)) {
				
				String transferMode=String.valueOf(request.getParameter("transferType"));
				if (!"null".equalsIgnoreCase(transferMode)) {
					doAccountTransferLogic(request, response, accountNumber,
							accountBalance, transactionAmount, transactionBean,
							transferMode);
				}
				else{
					doWithdrawLogic(response, accountNumber, accountBalance,
							transactionAmount, transactionBean);
				}
			}
		}

	}

	/**
	 * @param request
	 * @param response
	 * @param accountNumber
	 * @param accountBalance
	 * @param transactionAmount
	 * @param transactionBean
	 * @param transferMode
	 * @throws IOException
	 */
	private void doAccountTransferLogic(HttpServletRequest request,
			HttpServletResponse response, String accountNumber,
			String accountBalance, double transactionAmount,
			TransactionBean transactionBean, String transferMode)
			throws IOException {
		//To A/c Set
		String txtBeneficiaryAcNo = String.valueOf(request
				.getParameter("txtBeneficiaryAcNo"));
		transactionBean.setToAccountNo(txtBeneficiaryAcNo);
		//Set ToIFSC
		try {
			String toIFSC=depositWithdrawlCash.getDataFromTablesUsingCondition("Beneficiary_IFSC", "BENEFICIARY_ACCOUNT", "where " +
					"Primary_Account_Id='"+accountNumber+"' and Beneficiary_Ac_No='"+txtBeneficiaryAcNo+"'").get(1)[0];
			transactionBean.setToIFSC(toIFSC);
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		//Set Transaction Description 
		String txtTransDescription = String.valueOf(request
				.getParameter("txtTransDescription"));
		transactionBean.setDescription(transferMode+"--"+txtTransDescription);
		//Set Transaction Type Dr/Cr
		transactionBean.setTransType("Dr");
		
		//Perform Transfer Logic
		try {
			if (depositWithdrawlCash.isAmtWithdrawled(transactionBean)) {
				response.getWriter().write(
						"Rs.:" + transactionAmount
								+ " Successfully Transfered to A/c No: "+ txtBeneficiaryAcNo +  " <br/>");
				accountBalance = String.valueOf(depositWithdrawlCash
						.getAvailableBalance(accountNumber));
				response.getWriter().write(
						"Available Balance:" + accountBalance);
			} else {
				response.getWriter()
						.write("Unable to Transfer the Amount...Try Later");
			}
		} catch (SQLException e) {
			response.getWriter()
			.write("Unable to Transfer the Amount...Try Later"+e.getMessage());
		} catch (ClassNotFoundException e) {
			response.getWriter()
			.write("Unable to Transfer the Amount...Try Later"+e.getMessage());
		} catch (TransactionException e) {
			response.getWriter()
			.write("Unable to Transfer the Amount...Try Later"+e.getMessage());
		}
	}

	private void deleteBeneficiaryAccount(HttpServletResponse response,
			String pAcNo, String bAcNo) throws IOException {

		String deleteBeneficiaryQuery = "DELETE from BENEFICIARY_ACCOUNT where Primary_Account_Id='"
				+ pAcNo + "' and Beneficiary_Ac_No='" + bAcNo + "'";
		System.out.println(deleteBeneficiaryQuery);
		String queries[] = { deleteBeneficiaryQuery };
		try {
			if (dmlOperaionDbManager.isQueryExecuted(queries)) {
				response.getWriter().write(
						"Beneficiary Successfully Removed from Your Account<br/>");
			} else {
				response.getWriter().write("Can't delete Beneficiary<br/>");
			}
		} catch (ClassNotFoundException e) {
			response.getWriter().write(
					"Can't delete Beneficiary" + e.getMessage() + "<br/>");
		} catch (SQLException e) {
			response.getWriter().write(
					"Can't delete Beneficiary" + e.getMessage() + "<br/>");
		}
	
		
	}

	/**
	 * @param response
	 * @param pAcNo
	 * @param bAcNo
	 * @param bAcName
	 * @param bIFSC
	 * @param bEmail
	 * @param bPhNo
	 * @param bBankName TODO
	 * @throws IOException
	 */
	private void addBeneficiaryAccount(HttpServletResponse response,
			String pAcNo, String bAcNo, String bAcName, String bIFSC,
			String bEmail, String bPhNo, String bBankName) throws IOException {
		String addBeneficiaryQuery = "Insert into BENEFICIARY_ACCOUNT values('"
				+ pAcNo + "','" + bAcNo + "','" + bAcName + "','" + bIFSC
				+ "','" + bEmail + "','" + bPhNo + "','" + bBankName+"')";
		System.out.println(addBeneficiaryQuery);
		String queries[] = { addBeneficiaryQuery };
		try {
			if (dmlOperaionDbManager.isQueryExecuted(queries)) {
				response.getWriter().write(
						"Beneficiary Successfully Added into Your Account<br/>");
			} else {
				response.getWriter().write("Can't add Beneficiary<br/>");
			}
		} catch (ClassNotFoundException e) {
			response.getWriter().write(
					"Can't add Beneficiary" + e.getMessage() + "<br/>");
		} catch (SQLException e) {
			response.getWriter().write(
					"Can't add Beneficiary" + e.getMessage() + "<br/>");
		}
	}

	/**
	 * @param response
	 * @param accountNumber
	 * @param accountBalance
	 * @param transactionAmount
	 * @param transactionBean
	 * @throws IOException
	 */
	private void doWithdrawLogic(HttpServletResponse response,
			String accountNumber, String accountBalance,
			double transactionAmount, TransactionBean transactionBean)
			throws IOException {
		transactionBean.setTransType("Dr");
		transactionBean.setDescription("Self Withdraw");
		try {
			if (depositWithdrawlCash.isAmtWithdrawled(transactionBean)) {
				response.getWriter().write(
						"Rs.:" + transactionAmount
								+ " Withdrawn Successfully<br/>");
				accountBalance = String.valueOf(depositWithdrawlCash
						.getAvailableBalance(accountNumber));
				response.getWriter().write(
						"Available Balance:" + accountBalance);
			} else {
				response.getWriter()
						.write("Amount can't be withdrwn due to server problem...Try Later");
			}
		} catch (NumberFormatException e) {
			response.getWriter().write(
					"Amount can't be withdrwn due to following problem...Try Later<br/>"
							+ e.getMessage());
		} catch (SQLException e) {
			response.getWriter().write(
					"Amount can't be withdrwn due to following problem...Try Later<br/>"
							+ e.getMessage());
		} catch (ClassNotFoundException e) {
			response.getWriter().write(
					"Amount can't be withdrwn due to following problem...Try Later<br/>"
							+ e.getMessage());
		} catch (TransactionException e) {
			response.getWriter().write(
					"Amount can't be withdrwn due to following problem...Try Later<br/>"
							+ e.getMessage());
		}
	}

	/**
	 * @param response
	 * @param accountNumber
	 * @param accountBalance
	 * @param transactionAmount
	 * @param transactionBean
	 * @throws IOException
	 */
	private void doDepositLogic(HttpServletResponse response,
			String accountNumber, String accountBalance,
			double transactionAmount, TransactionBean transactionBean)
			throws IOException {
		transactionBean.setTransType("Cr");
		transactionBean.setDescription("Self Deposit");
		try {
			try {
				if (depositWithdrawlCash.isAmtDeposited(transactionBean)) {
					response.getWriter().write(
							"Rs.:" + transactionAmount
									+ " Deposited Successfully<br/>");
					accountBalance = String.valueOf(depositWithdrawlCash
							.getAvailableBalance(accountNumber));
					response.getWriter().write(
							"Available Balance:" + accountBalance);
				} else {
					response.getWriter()
							.write("Amount can't be dopsited due to server problem...Try Later");
				}
			} catch (TransactionException e) {
				response.getWriter().write(
						"Amount can't be dopsited due to followin problem...Try Later<br/>"
								+ e.getMessage());
			}
		} catch (NumberFormatException e) {
			response.getWriter().write(
					"Amount can't be dopsited due to following problem...Try Later<br/>"
							+ e.getMessage());
		} catch (SQLException e) {
			response.getWriter().write(
					"Amount can't be dopsited due to following problem...Try Later<br/>"
							+ e.getMessage());
		} catch (ClassNotFoundException e) {
			response.getWriter().write(
					"Amount can't be dopsited due to following problem...Try Later<br/>"
							+ e.getMessage());
		}
	}

	/** Sets From IFSC in TransBean
	 * @param accountNumber
	 * @param transactionBean
	 */
	private void setFromIFSCInTransactionBean(String accountNumber,
			TransactionBean transactionBean) {
		
		try {
			Map<Integer, String[]> map = depositWithdrawlCash
					.getDataFromTablesUsingCondition("IFSC",
							"AccountInformation", " where Account_Id='"
									+ accountNumber + "'");
			/*
			 * for(String[] str:map.values()){ for(String s:str){
			 * System.out.print(s+"\t"); } System.out.println(); }
			 */
			transactionBean.setFromIFSC(map.get(1)[0]);
		} catch (SQLException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (ClassNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}
	/**
	 * Sets Transaction Time in TransBean
	 * @param transactionBean
	 */
	private void setTransactionTime(TransactionBean transactionBean){
		java.util.Date today = new java.util.Date();
		java.sql.Timestamp sqlToday = new java.sql.Timestamp(today.getTime());
		String transactionDateTime = sqlToday.toString();
		transactionBean.setTransTimeStamp(transactionDateTime);
	}
	/**
	 * Sets Transaction Amount in TransBean
	 * @param transactionAmount
	 * @param transactionBean
	 */
	private void setTransactionAmount(double transactionAmount, TransactionBean transactionBean){
		transactionBean.setAmount(transactionAmount);
	}
	

	/**
	 * @param response
	 * @param accountNumber
	 * @param accountBalance
	 * @throws IOException
	 */
	private void showAvailableBalance(HttpServletResponse response,
			String accountNumber, String accountBalance) throws IOException {
		try {
			accountBalance = String.valueOf(depositWithdrawlCash
					.getAvailableBalance(accountNumber));
		} catch (SQLException e) {
			response.getWriter()
					.write("Unable to retrieve current account balance due to following problem...Try Later<br/>"
							+ e.getMessage());
		} catch (ClassNotFoundException e) {
			response.getWriter()
					.write("Unable to retrieve current account balance due to following problem...Try Later<br/>"
							+ e.getMessage());
		}
		response.getWriter().write("Available Balance:" + accountBalance);
	}
}
